/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.game.math.view.domain;

import java.util.Observable;
import java.util.Observer;
import java.util.ResourceBundle;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author nmduc
 */
public class ExpressionTableModel extends AbstractTableModel implements Observer {

    private Examination examination;
    private static ResourceBundle bundle = ResourceBundle.getBundle("org.game.math.view.domain.ExpressionTableModel");
    public ExpressionTableModel() {
        this.examination = Examination.getInstance();
        this.examination.addObserver(this);
    }

    public Examination getExamination() {
        return examination;
    }

    @Override
    public int getRowCount() {
        if (this.examination != null) {
            return this.examination.getExpressionList().size();
        }
        return 0;
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    @Override
    public Object getValueAt(int row, int col) {

        if (!isValidatedRowIndex(row)) {
            throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
        }
        if (!isValidatedColumnIndex(col)) {
            throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
        }
        MathExpression expression = this.examination.getExpressionList().get(row);
        switch (col) {
            case 0:
                return expression.getExpression();
            default:
                return expression.getInputResult();
        }
    }

    @Override
    public Class<?> getColumnClass(int i) {
        return String.class;
    }

    @Override
    public String getColumnName(int col) {
        if (isValidatedColumnIndex(col)) {
            switch (col) {
                case 0:
                    return bundle.getString("col_0.name");
                default:
                    return bundle.getString("col_1.name");
            }
        } else {
            throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
        }
    }

    @Override
    public boolean isCellEditable(int row, int col) {
        if (!isValidatedRowIndex(row)) {
            throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
        }
        if (!isValidatedColumnIndex(col)) {
            throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
        }
        MathExpression expression = examination.getExpressionList().get(row);
        return expression.isCorrected() == null && col == 1;
    }

    @Override
    public void setValueAt(Object value, int row, int col) {

        if (!isValidatedRowIndex(row)) {
            throw new IndexOutOfBoundsException("row selected is " + row + " but cannot found in the table.");
        }
        if (!isValidatedColumnIndex(col)) {
            throw new IndexOutOfBoundsException("col selected is " + col + " but cannot found in the table.");
        }
        if (col != 1) {
            throw new IndexOutOfBoundsException("Only cells at column 1 can be edited");
        }
        this.examination.getExpressionList().get(row).setInputResult((String) value);

    }

    private boolean isValidatedColumnIndex(int col) {
        return col >= 0 && col < 2;
    }

    private boolean isValidatedRowIndex(int row) {
        return row >= 0 && row < this.getRowCount();
    }

    @Override
    public void update(Observable o, Object o1) {
        this.fireTableDataChanged();
    }
}
